package com.cn.xiaonuo.tcrfinance.tcrusers.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.xiaonuo.common.constant.SmsConstant;
import com.cn.xiaonuo.common.constant.Status;
import com.cn.xiaonuo.common.entity.BusinessMessage;
import com.cn.xiaonuo.common.utils.DateUtils;
import com.cn.xiaonuo.common.utils.ExportExcelUtils;
import com.cn.xiaonuo.common.utils.OrderNumGeneration;
import com.cn.xiaonuo.common.utils.TencentSmsUtils;
import com.cn.xiaonuo.common.vo.ExcelData;
import com.cn.xiaonuo.core.util.PoiUtil;
import com.cn.xiaonuo.core.util.RedisKeyUtil;
import com.cn.xiaonuo.tcrfinance.sysmgmt.entity.SysUserHpcEntity;
import com.cn.xiaonuo.tcrfinance.sysmgmt.mapper.SysUserHpcMapper;
import com.cn.xiaonuo.tcrfinance.sysmgmt.rsp.SysUserRsp;
import com.cn.xiaonuo.tcrfinance.tcrorder.entity.PvHoliday;
import com.cn.xiaonuo.tcrfinance.tcrorder.entity.PvOrder;
import com.cn.xiaonuo.tcrfinance.tcrorder.entity.PvPossessionGoods;
import com.cn.xiaonuo.tcrfinance.tcrorder.mapper.PvHolidayMapper;
import com.cn.xiaonuo.tcrfinance.tcrorder.mapper.PvOrderMapper;
import com.cn.xiaonuo.tcrfinance.tcrorder.mapper.PvPossessionGoodsMapper;
import com.cn.xiaonuo.tcrfinance.tcrorder.mapper.PvReleaseBaseMapper;
import com.cn.xiaonuo.tcrfinance.tcrshops.entity.PvProduct;
import com.cn.xiaonuo.tcrfinance.tcrshops.entity.PvProductGl;
import com.cn.xiaonuo.tcrfinance.tcrshops.entity.PvShop;
import com.cn.xiaonuo.tcrfinance.tcrshops.mapper.PvProductGlMapper;
import com.cn.xiaonuo.tcrfinance.tcrshops.mapper.PvProductMapper;
import com.cn.xiaonuo.tcrfinance.tcrtimes.service.HtTimeService;
import com.cn.xiaonuo.tcrfinance.tcrshops.mapper.PvShopMapper;
import com.cn.xiaonuo.tcrfinance.tcrusers.entity.*;
import com.cn.xiaonuo.tcrfinance.tcrusers.enums.HpcUserEnum;
import com.cn.xiaonuo.tcrfinance.tcrusers.mapper.*;
import com.cn.xiaonuo.tcrfinance.tcrusers.param.*;
import com.cn.xiaonuo.tcrfinance.tcrusers.service.LoginService;
import com.cn.xiaonuo.tcrfinance.tcrusers.service.PvLoginUserService;
import com.cn.xiaonuo.tcrfinance.tcrusers.service.WalletLogService;
import com.cn.xiaonuo.tcrfinance.tcrusers.vo.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.sun.org.apache.xpath.internal.operations.And;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static cn.hutool.core.date.DateTime.now;
@Slf4j
@Service
public class PvLoginUserServiceImpl extends ServiceImpl<PvLoginUserMapper, PvLoginUser> implements PvLoginUserService {


    @Autowired
    private PvPossessionGoodsMapper pvPossessionGoodsMapper;
    @Autowired
    private PvLoginUserMapper pvUserLoginMapper;
    @Autowired
    private PvProductGlMapper pvProductGlMapper;
    @Autowired
    private PvOrderMapper pvOrderMapper;
    @Autowired
    private PvWalletLogMapper pvWalletLogMapper;
    @Autowired
    private WalletLogService walletLogService;
    @Autowired
    private HpcUserMapper hpcUserMappers;
    @Autowired
    private PvUserLogMapper pvUserLogMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysUserHpcMapper sysUserHpcMapper;
    @Autowired
    private PvProductMapper pvProductMapper;
    @Autowired
    private CancelExperienceLogMapper cancelExperienceLogMapper;
    @Autowired
    private LoginService loginService;
    @Autowired
    private PvWalletMapper pvWalletMapper;
    @Autowired
    private PvReleaseBaseMapper pvReleaseBaseMapper;
    @Autowired
    private Environment env;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private HtTimeService htTimeService;
    @Autowired
    private PvHolidayMapper pvHolidayMapper;
    @Autowired
    private PvWalletShopLogMapper pvWalletShopLogMapper;
    @Autowired
    private PvShopMapper pvShopMapper;

    @Override
    public BusinessMessage queryUserList(UserListParam params) {
        BusinessMessage<Object> message = new BusinessMessage<>();
        Integer pageNo = params.getPageNo();
        Integer pageSize = params.getPageSize();
        if (pageNo == null || pageNo <= 0) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }
        // 设置分页参数
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> lists = pvUserLoginMapper.queryUserList(params);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(lists);
        message.setSuccess(true);
        message.setData(pageInfo);
        message.setCode("200");
        message.setMessage("查询成功");
        return message;
    }

    /**
     * 资产信息
     */
    @Override
    public BusinessMessage capitalInfo(Map<String, Object> params) {
        BusinessMessage<Object> message = new BusinessMessage<>();
        try {
            String accounts = Convert.toStr(params.get("accounts"));
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String curTime = null;
            if (params.get("curTime") instanceof String) {
                curTime = simpleDateFormat.format(new Date(Long.parseLong((String) params.get("curTime"))));
            }
            if (params.get("curTime") instanceof Long) {
                curTime = simpleDateFormat.format(new Date((Long) params.get("curTime")));
            }

            Map<String, Object> resultMap = new HashMap<>();
            //1.买入金额
            Double buySumTotalAmount = pvUserLoginMapper.buySumTotalAmount(accounts, curTime);
            resultMap.put("buySumTotalAmount", buySumTotalAmount == null ? 0 : buySumTotalAmount);
            //2.卖出金额
            Double sellSumTotalAmount = pvUserLoginMapper.sellSumTotalAmount(accounts, curTime);
            resultMap.put("sellSumTotalAmount", sellSumTotalAmount == null ? 0 : sellSumTotalAmount);
            //3.出金
            Double cGoldSumTotalAmount = pvUserLoginMapper.cGoldSumTotalAmount(accounts, curTime);
            resultMap.put("cGoldSumTotalAmount", cGoldSumTotalAmount == null ? 0 : cGoldSumTotalAmount);
            //4.入金
            Double rGoldSumTotalAmount = pvUserLoginMapper.rGoldSumTotalAmount(accounts, curTime);
            resultMap.put("rGoldSumTotalAmount", rGoldSumTotalAmount == null ? 0 : rGoldSumTotalAmount);
            //5.总账号手续费
            Double costTotalAmount = pvUserLoginMapper.costTotalAmount(accounts, curTime);
            costTotalAmount = costTotalAmount == null ? 0 : costTotalAmount;
            resultMap.put("costTotalAmount", costTotalAmount);

          /*  Double queryBuySellSumSeven = pvUserLoginMapper.queryBuySellSumSeven(accounts, curTime);
            resultMap.put("queryBuySellSumSeven", queryBuySellSumSeven == null ? 0 : queryBuySellSumSeven);*/
            //6.当天初始余额和当天最后一次交易之后的余额
            List<Map<String, Object>> walletList = pvUserLoginMapper.queryWalletLogByDate(accounts, curTime);
            if (walletList != null && walletList.size() > 0) {
                //第一个
                Map<String, Object> farstMap = walletList.get(0);
                //最后一个
                Map<String, Object> lastMap = walletList.get(walletList.size() - 1);
                resultMap.put("endBalance", farstMap.get("after_change_balance") == null ? 0 : farstMap.get("after_change_balance"));
                resultMap.put("beginBalance", lastMap.get("before_change_balance") == null ? 0 : lastMap.get("before_change_balance"));
            }
            PvProductGl pvProductGl = pvProductGlMapper.selectOne(new QueryWrapper<>(new PvProductGl() {{
                setSellUserId(Convert.toInt(accounts));
            }}));
            if (pvProductGl != null) {
                Double totalPoundageSum = pvWalletLogMapper.totalPoundageSum(pvProductGl.getPoundageUserId(), curTime);
                totalPoundageSum = totalPoundageSum == null ? 0 : totalPoundageSum;
                resultMap.put("totalPoundageSum", totalPoundageSum);
                BigDecimal userBuySellSum = Convert.toBigDecimal(totalPoundageSum).subtract(Convert.toBigDecimal(costTotalAmount));
                resultMap.put("userBuySellSum", userBuySellSum);
            } else {
                resultMap.put("totalPoundageSum", 0);
                resultMap.put("userBuySellSum", 0);
            }

            List<Map<String, Object>> resultList = new ArrayList<>();
            resultList.add(resultMap);
            message.setData(resultList);
            message.setMessage("200");
            message.setSuccess(true);
            message.setMessage("操作成功");
            return message;
        } catch (Exception e) {
            e.printStackTrace();
        }
        message.setCode("-1");
        message.setSuccess(false);
        message.setMessage("操作失败");
        return message;
    }

    /**
     * 当日买卖记录
     *
     * @param params
     * @return
     */
    @Override
    public BusinessMessage queryBuySellByDate(Map<String, Object> params) {
        BusinessMessage<Object> message = new BusinessMessage<>();
        Integer pageNo = null;
        Integer pageSize = null;
        if (params.get("pageNo") instanceof Integer) {
            pageNo = (Integer) params.get("pageNo");
        } else if (params.get("pageNo") instanceof String) {
            String pageNo1 = (String) params.get("pageNo");
            pageNo = Integer.parseInt(pageNo1);
        }
        if (params.get("pageSize") instanceof Integer) {
            pageSize = (Integer) params.get("pageSize");
        } else if (params.get("pageSize") instanceof String) {
            String pageSize1 = (String) params.get("pageSize");
            pageSize = Integer.parseInt(pageSize1);
        }
        if (pageNo == null || pageNo <= 0) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }
        String accounts = null;
        if (params.get("accounts") instanceof String) {
            accounts = (String) params.get("accounts");
        }
        if (params.get("accounts") instanceof Integer) {
            accounts = String.valueOf((Integer) params.get("accounts"));
        }
        if (params.get("accounts") instanceof Long) {
            accounts = String.valueOf((Long) params.get("accounts"));
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String curTime = null;
        if (params.get("curTime") instanceof String) {
            curTime = simpleDateFormat.format(new Date(Long.parseLong((String) params.get("curTime"))));
        }
        if (params.get("curTime") instanceof Long) {
            curTime = simpleDateFormat.format(new Date((Long) params.get("curTime")));
        }
        Map<Object, Object> resultMap = new HashMap<>();
        Double queryBuySellSumNum = pvUserLoginMapper.queryBuySellSumNum(accounts, curTime);
        Double queryBuySellSumMoney = pvUserLoginMapper.queryBuySellSumMoney(accounts, curTime);
        Double queryBuySellSumSXF = pvUserLoginMapper.queryBuySellSumSXF(accounts, curTime);
        Double queryBuySellSumSeven = pvUserLoginMapper.queryBuySellSumSeven(accounts, curTime);

        // 设置分页参数
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> lists = pvUserLoginMapper.queryBuySellByDate(accounts, curTime);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(lists);
        List<String> orderIdList = null;
        if (lists != null && lists.size() >= 0) {
            resultMap.put("queryBuySellSumNum", queryBuySellSumNum == null ? 0 : queryBuySellSumNum);
            resultMap.put("queryBuySellSumMoney", queryBuySellSumMoney == null ? 0 : queryBuySellSumMoney);
            resultMap.put("queryBuySellSumSXF", queryBuySellSumSXF == null ? 0 : queryBuySellSumSXF);
            resultMap.put("queryBuySellSumSeven", queryBuySellSumSeven == null ? 0 : queryBuySellSumSeven);
            resultMap.put("pageInfo", pageInfo);
            message.setSuccess(true);
            message.setData(resultMap);
            message.setCode("200");
            message.setMessage("查询成功");
            return message;
        }
        message.setCode("-1");
        message.setSuccess(false);
        message.setMessage("操作失败");
        return message;
    }

    /**
     * 持有商品记录
     */
    @Override
    public BusinessMessage queryHoldProductList(HoldProductListParam params) {
        BusinessMessage<Object> message = new BusinessMessage<>();
        if (ObjectUtils.isEmpty(params.getAccounts()) || ObjectUtils.isEmpty(params.getCurTime())) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("参数不完整!");
            return message;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            String curTime = null;
            String yesterday = null;
            curTime = simpleDateFormat.format(new Date((Long) params.getCurTime()));
            Date toDayDate = simpleDateFormat.parse(curTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(toDayDate);
            calendar.add(Calendar.DAY_OF_MONTH, -1);//减一天
            yesterday = simpleDateFormat.format(calendar.getTime());
            List<HoldProductEntity> list = getHoldProductEntities(params, curTime, yesterday);
            message.setSuccess(true);
            message.setData(list);
            message.setCode("200");
            message.setCode("查询成功");
            return message;
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

    @NotNull
    private List<HoldProductEntity> getHoldProductEntities(HoldProductListParam param, String curTime, String yesterday) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        LambdaQueryWrapper<PvPossessionGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PvPossessionGoods::getUserId, Integer.valueOf(param.getAccounts()));
        if (ObjectUtils.isNotEmpty(param.getProductId())){
            queryWrapper.eq(PvPossessionGoods::getProductId, param.getProductId());
        }
        List<PvPossessionGoods> goodList = pvPossessionGoodsMapper.selectList(queryWrapper);
//        List<Map<String, Object>> list = new ArrayList<>();
        List<HoldProductEntity> list = new ArrayList<>();
        for (PvPossessionGoods pvPossessionGoods1 : goodList) {
//            Map<String, Object> goodMap = new HashMap<>();
            HoldProductEntity goodMap = new HoldProductEntity();
            goodMap.setProductId(pvPossessionGoods1.getProductId());
            goodMap.setProductName(pvPossessionGoods1.getProductName());
            QueryWrapper<PvProduct> queryWrapper1 = new QueryWrapper();
            queryWrapper1.eq("id", pvPossessionGoods1.getProductId());
            PvProduct pvProduct = pvProductMapper.selectOne(queryWrapper1);
            LambdaQueryWrapper<PvProductGl> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PvProductGl::getSellUserId, pvPossessionGoods1.getUserId());

            lambdaQueryWrapper.eq(PvProductGl::getShopId, pvProduct.getShopId());

            PvProductGl pvProductGl = pvProductGlMapper.selectOne(lambdaQueryWrapper);
            PvShop pvShop = pvShopMapper.selectOne(new QueryWrapper<>(new PvShop() {{
                setId(pvProduct.getShopId());
            }}));
            goodMap.setShopId(pvShop.getId());
            goodMap.setShopName(pvShop.getShopName());
            //1.上日持有总数量
            Double srDayHoldNum = pvUserLoginMapper.drSumNum(pvPossessionGoods1.getUserId() + "",
                    yesterday,
                    pvPossessionGoods1.getProductId() + "");
            Double srSFNumProduct = 0d;
            if (pvProductGl != null) {
                srSFNumProduct = pvUserLoginMapper.querySFSumNumByProductId(
                        curTime,
                        pvPossessionGoods1.getProductId() + "");
            }

            if (srSFNumProduct != null) {
                goodMap.setSrDayHoldNum(srDayHoldNum == null ? 0 : srDayHoldNum - srSFNumProduct);
            } else {
                goodMap.setSrDayHoldNum(srDayHoldNum == null ? 0 : srDayHoldNum);
            }
            //2.当日可用数量
            Double drDayAvaNum = pvUserLoginMapper.drDayAvaNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setDrDayAvaNum(drDayAvaNum == null ? 0 : drDayAvaNum);
            //3.匀贸兑换数量
            goodMap.setYmExNum(0);
            //4.已释放数量
            goodMap.setYmSFNum(0);
            //5.当日买入数量
            Double drDayBuyNum = pvUserLoginMapper.queryBuySumNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setDrDayBuyNum(drDayBuyNum == null ? 0 : drDayBuyNum);
            //6.当日卖出数量
            Double drDaySellNum = pvUserLoginMapper.querySellSumNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setDrDaySellNum(drDaySellNum == null ? 0 : drDaySellNum);
            //7.当日释放数量
            Double drSFNum = pvUserLoginMapper.querySFSumNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setDrSFNum(drSFNum == null ? 0 : drSFNum);
            //当日扣除对应商品的总释放量


            Double drSFNumProductId = 0d;
            Date dd = null;
            try {
                dd = simpleDateFormat.parse(curTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dd);
            calendar.add(Calendar.DAY_OF_MONTH, 1);//加一天
            if (pvProductGl != null) {
                drSFNumProductId = pvUserLoginMapper.querySFSumNumByProductId(
                        simpleDateFormat.format(calendar.getTime()),
                        pvPossessionGoods1.getProductId() + "");
                goodMap.setDrSFNumProductId(drSFNumProductId == null ? 0 : drSFNumProductId);
            } else {
                goodMap.setDrSFNumProductId(0D);
            }
            //8.当日卖出释放数量
            Double drSellSFNum = pvUserLoginMapper.querySellSFNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setDrSellSFNum(drSellSFNum == null ? 0 : drSellSFNum);
            //9.当日提货数量
            Double queryTHNum = pvUserLoginMapper.queryTHNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setDrTHNum(queryTHNum == null ? 0 : queryTHNum);
            //10.当日持有总数量
            Double drSumNum = pvUserLoginMapper.drSumNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            if (drSFNumProductId != null) {
                goodMap.setDrSumNum(drSumNum == null ? 0 : drSumNum - drSFNumProductId);
            } else {
                goodMap.setDrSumNum(drSumNum == null ? 0 : drSumNum);
            }
            //11.已提货总数量
            Double queryTHSumNum = pvUserLoginMapper.queryTHSumNum(pvPossessionGoods1.getUserId() + "",
                    curTime,
                    pvPossessionGoods1.getProductId() + "");
            goodMap.setYjTHNum(queryTHSumNum == null ? 0 : queryTHSumNum);
            goodMap.setDcDate(curTime);
            list.add(goodMap);
        }
        return list;
    }

    //撤销线下打款操作。
    @Override
    @Transactional
    public BusinessMessage cancelPaymentOperation(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer loginUserId = null;
            if (params.get("loginUserId") instanceof Integer) {
                loginUserId = (Integer) params.get("loginUserId");
            }
            if (params.get("loginUserId") instanceof String) {
                if (StringUtils.isNotBlank((String) params.get("loginUserId"))) {
                    loginUserId = Integer.valueOf((String) params.get("loginUserId"));
                } else {
                    message.setSuccess(false);
                    message.setCode("-1");
                    message.setMessage("loginUserId不能为空");
                    return message;
                }
            }

            Integer id = null;
            if (params.get("id") instanceof Integer) {
                id = (Integer) params.get("id");
            }
            if (params.get("id") instanceof String) {
                if (StringUtils.isNotBlank((String) params.get("id"))) {
                    id = Integer.valueOf((String) params.get("id"));
                } else {
                    message.setSuccess(false);
                    message.setCode("-1");
                    message.setMessage("订单id不能为空");
                    return message;
                }
            }

            //查询出要取消的订单对象
            PvOrder pvOrder = pvOrderMapper.selectById(id);
            pvOrder.setPaymentState(2);
            pvOrder.setRemark(pvOrder.getRemark() + ",撤销该线下充值");
            pvOrder.setUpdatedAt(new Date());
            pvOrderMapper.updateById(pvOrder);

            boolean status = this.moneyOperation(pvOrder.getDelistingUserId(), 2, pvOrder.getTotalAmount());
            if (false == status) {
                message.setSuccess(false);
                message.setCode("-1");
                message.setMessage("撤销线下充值不符合撤销条件，可用余额小于充值金额");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return message;
            }
            String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            pvWalletLogMapper.insertWalletLogByUserId(pvOrder.getDelistingUserId(), pvOrder.getId(), pvOrder.getTotalAmount(), "撤销线下充值", currentTime, 8, loginUserId);
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("撤销线下充值成功");
            return message;
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("撤销线下充值失败");
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return message;
    }

    /**
     * 资金操作
     *
     * @param userId 用户id
     * @param types  1:加钱 2:扣钱
     * @param money  多少钱
     * @return
     */
    public boolean moneyOperation(Integer userId, Integer types, BigDecimal money) throws Exception {
        boolean status = false;
        try {
            Integer i = pvWalletLogMapper.updateWalletInfoByUserId(userId, money, types);
            if (i == 1) {
                status = true;
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }
        return status;
    }

    //线下银行卡充值记录
    @Override
    public BusinessMessage offlineRechargeDetailed(PvUserReParam onlineUserReParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            PvUserEntity onlineUserRecharge = new PvUserEntity();
            BeanUtil.copyProperties(onlineUserReParam, onlineUserRecharge);
            Integer pageSize = onlineUserReParam.getPageSize();
            Integer pageNo = onlineUserReParam.getPageNo();
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            if (null != onlineUserReParam.getBeginTime() && null != onlineUserReParam.getEndTime()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.conversionTime(onlineUserReParam.getBeginTime(), onlineUserReParam.getEndTime());
                onlineUserRecharge.setBeginTime(map.get("begin"));
                onlineUserRecharge.setEndTime(map.get("end"));
            }

            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> resultList = pvUserLoginMapper.offlineRechargeDetailed(onlineUserRecharge);
            if (null == resultList || resultList.size() < 0) {
                message.setMessage("无数据");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("sumMoney", pvUserLoginMapper.offlineRechargeDetailedTotal(onlineUserRecharge));
            resultMap.put("pageInfo", pageInfo);
            message.setData(resultMap);
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("操作成功");
            return message;
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("操作失败");
            e.printStackTrace();
        }
        return message;
    }

    @Override
    public BusinessMessage queryUserYZBankCardInfo(PvUserReParam pvUserReParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            PvUserEntity pvUserEntity = new PvUserEntity();
            BeanUtil.copyProperties(pvUserReParam, pvUserEntity);
            Integer pageSize = pvUserReParam.getPageSize();
            Integer pageNo = pvUserReParam.getPageNo();
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            if (null != pvUserReParam.getBeginTime() && null != pvUserReParam.getEndTime()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.conversionTime(pvUserReParam.getBeginTime(), pvUserReParam.getEndTime());
                pvUserEntity.setBeginTime(map.get("begin"));
                pvUserEntity.setEndTime(map.get("end"));
            }
            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> resultList = pvUserLoginMapper.queryUserYZBankCardInfo(pvUserEntity);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
            Double totalAmountSUM = pvUserLoginMapper.queryUserYZBankCardInfoSUM(pvUserEntity);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("totalAmountSUM", totalAmountSUM);
            resultMap.put("pageInfo", pageInfo);
            message.setData(resultMap);
            message.setMessage("操作成功");
            message.setCode("200");
            message.setSuccess(true);
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("操作失败");
            e.printStackTrace();
        }
        return message;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage cancelTX(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer loginUserId = Convert.toInt(params.get("loginUserId"));
            Integer orderId = Convert.toInt(params.get("orderId"));
            String operationName = Convert.toStr(params.get("operationName"));
            PvOrder pvOrder = pvOrderMapper.selectById(orderId);
            if (pvOrder.getPaymentState() != 2) {
                message.setSuccess(false);
                message.setMessage("该订单不正确");
                message.setCode("-1");
                return message;
            }
            pvOrder.setPaymentState(102);
            pvOrder.setUpdatedAt(new Date());
            pvOrder.setUserId(loginUserId);
            pvOrder.setOperationName(operationName);
            pvOrderMapper.updateById(pvOrder);
            //给提现用户添加金额
            boolean status = this.moneyOperation(pvOrder.getDelistingUserId(), 1, pvOrder.getTotalAmount());
            if (false == status) {
                message.setCode("-1");
                message.setMessage("添加金额失败");
                message.setSuccess(false);
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return message;
            }
            walletLogService.walletLogs(pvOrder.getDelistingUserId(), pvOrder.getId(), null, pvOrder.getTotalAmount(), 9, "操作人：" + loginUserId);
            message.setMessage("操作成功");
            message.setCode("200");
            message.setSuccess(true);
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("操作失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }
        return message;
    }

    @Override
    public BusinessMessage selectUserInfoAndWallet(PvUserReParam pvUserReParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            PvUserEntity pvUserEntity = new PvUserEntity();
            BeanUtil.copyProperties(pvUserReParam, pvUserEntity);
            Integer pageSize = pvUserReParam.getPageSize();
            Integer pageNo = pvUserReParam.getPageNo();
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            if (null != pvUserReParam.getBeginTime() && null != pvUserReParam.getEndTime()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.conversionTime(pvUserReParam.getBeginTime(), pvUserReParam.getEndTime());
                pvUserEntity.setBeginTime(map.get("begin"));
                pvUserEntity.setEndTime(map.get("end"));
            }
            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> resultList = pvUserLoginMapper.selectUserInfoAndWallet(pvUserEntity);
            if (null == resultList || resultList.size() < 0) {
                message.setMessage("操作失败");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
            Map<Object, Object> resultMap = new HashMap<>();
            resultMap.put("pageInfo", pageInfo);
            resultMap.put("sumMoney", pvUserLoginMapper.selectUserInfoAndWalletSumMoney(pvUserEntity));
            message.setData(resultMap);
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("操作成功");
            return message;
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("操作失败");
            e.printStackTrace();
        }
        return message;
    }

    //查询所有用户信息和资金信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage offlineRecharge(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer userId = Convert.toInt(params.get("userId"));
            if (userId == null) {
                message.setSuccess(false);
                message.setCode("-1");
                message.setMessage("userId不能为空");
                return message;
            }
            Integer loginUserId = null;
            if (params.get("loginUserId") instanceof Integer) {
                loginUserId = (Integer) params.get("loginUserId");
            }
            if (params.get("loginUserId") instanceof String) {
                if (StringUtils.isNotBlank((String) params.get("loginUserId"))) {
                    loginUserId = Integer.valueOf((String) params.get("loginUserId"));
                } else {
                    message.setSuccess(false);
                    message.setCode("-1");
                    message.setMessage("loginUserId不能为空");
                    return message;
                }
            }
            BigDecimal offlineRechargeAmount = null;
            if (params.get("offlineRechargeAmount") instanceof String) {
                if (StringUtils.isNotBlank((String) params.get("offlineRechargeAmount"))) {
                    offlineRechargeAmount = BigDecimal.valueOf(Double.valueOf((String) params.get("offlineRechargeAmount")));
                } else {
                    message.setSuccess(false);
                    message.setCode("-1");
                    message.setMessage("购货金额不能为空");
                    return message;
                }
            }
            if (params.get("offlineRechargeAmount") instanceof BigDecimal) {
                offlineRechargeAmount = (BigDecimal) params.get("offlineRechargeAmount");
            }
            if (params.get("offlineRechargeAmount") instanceof Double) {
                offlineRechargeAmount = BigDecimal.valueOf((Double) params.get("offlineRechargeAmount"));
            }
            //type=1表示搜了宝充值
            Integer type = 0;
            if (params.get("type") instanceof Integer) {
                type = (Integer) params.get("type");
            }
            String orderNumParam = null;
            if (params.get("orderNum") instanceof String) {
                orderNumParam = (String) params.get("orderNum");
            }
            Integer paymentChannel = null;
            if (params.get("paymentChannel") instanceof Integer) {
                paymentChannel = (Integer) params.get("paymentChannel");
            }
            //生成订单明细
            PvOrder pvOrder = new PvOrder();
            String orderNum = OrderNumGeneration.generateOrderId();  //生成订单号
            if (type.equals(1)) {
                pvOrder.setSerialNumber("S" + orderNumParam);
            } else {
                pvOrder.setSerialNumber(orderNum);
            }
            if (type.equals(1)) {
                pvOrder.setRemark("搜了宝充值:" + offlineRechargeAmount);
            } else {
                pvOrder.setRemark("用户支付购货金额:" + offlineRechargeAmount);
            }
            pvOrder.setPurchaseMethod(3);
            String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            pvOrder.setCreateTime(currentTime);
            pvOrder.setUpdatedAt(new Date());
            pvOrder.setDelistingUserId(userId);
            pvOrder.setPaymentState(1);
            if (type.equals(1)) {
                pvOrder.setPaymentChannel(paymentChannel);
            } else {
                PvProductGl pvProductGl = pvProductGlMapper.selectOne(new QueryWrapper<>(new PvProductGl() {{
                    setSellUserId(userId);
                }}));
                pvOrder.setPaymentChannel(3);
                if (pvProductGl != null) {
                    pvOrder.setPaymentChannel(22);
                }
            }
            pvOrder.setTotalAmount(offlineRechargeAmount);
            pvOrderMapper.insert(pvOrder);
            boolean status = this.moneyOperation(userId, 1, offlineRechargeAmount);
            if (false == status) {
                message.setSuccess(false);
                message.setCode("-2");
                message.setMessage("用户支付购货金额失败");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return message;
            }
            if (type.equals(1)) {
                pvWalletLogMapper.insertWalletLogByUserId(userId, pvOrder.getId(), offlineRechargeAmount, "搜了宝充值:" + offlineRechargeAmount, currentTime, 3, loginUserId);
            } else {
                pvWalletLogMapper.insertWalletLogByUserId(userId, pvOrder.getId(), offlineRechargeAmount, "线下充值", currentTime, 3, loginUserId);
            }
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("支付成功");
            return message;
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("支付失败");
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return message;
    }

    @Override
    //************************************************后台信息个人信息修改***********************************************
    public BusinessMessage selectHtUserInfo(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            String accounts = null;
            if (params.get("accounts") instanceof String) {
                if (StringUtils.isNotBlank((String) params.get("accounts"))) {
                    accounts = (String) params.get("accounts");
                }
            }
            Integer pageNum = Integer.valueOf(params.get("pageNo") + "");
            Integer pageSize = Integer.valueOf(params.get("pageSize") + "");

            if (null == pageNum || Integer.valueOf(pageNum) <= 1) {
                pageNum = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> resultList = hpcUserMappers.selectHtUserInfo(accounts);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
            message.setData(pageInfo);
            message.setMessage("操作成功");
            message.setCode("200");
            message.setSuccess(true);
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("操作失败");
            e.printStackTrace();
        }
        return message;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage updateHtUserInfo(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            String phone = Convert.toStr(params.get("phone"));
            if (ObjectUtils.isEmpty(phone)) {
                message.setCode("-1");
                message.setSuccess(false);
                message.setMessage("参数不完整!");
                return message;
            }
            PvLoginUser loginUser = pvUserLoginMapper.selectById(new PvLoginUser() {{
                setId((Integer) params.get("id"));
            }});
            loginUser.setRealName(Convert.toStr(params.get("realname")));
            loginUser.setPhone(phone);
            loginUser.setCardNumber(Convert.toStr(params.get("cardnumber")));
            loginUser.setOpenBankAdd(Convert.toStr(params.get("openbankadd")));
            loginUser.setBankNumber(Convert.toStr(params.get("banknumber")));
            loginUser.setReservePhone(Convert.toStr(params.get("reservephone")));
            loginUser.setProvName(Convert.toStr(params.get("provName")));
            loginUser.setPreaName(Convert.toStr(params.get("preaName")));
            loginUser.setBankName(Convert.toStr(params.get("bankName")));
            pvUserLoginMapper.updateById(loginUser);
            //用户修改记录
            PvUserLog userLog = new PvUserLog();
            userLog.setUserId(loginUser.getId());
            userLog.setRemark("修改内容:"
                    + "姓名:" + loginUser.getRealName() + ">" + Convert.toStr(params.get("realname"))
                    + ",电话:" + loginUser.getPhone() + ">" + phone
                    + ",身份证:" + loginUser.getCardNumber() + ">" + Convert.toStr(params.get("cardnumber"))
                    + ",开户行地址:" + loginUser.getOpenBankAdd() + ">" + Convert.toStr(params.get("openbankadd"))
                    + ",银行卡号:" + loginUser.getBankNumber() + ">" + Convert.toStr(params.get("banknumber"))
                    + ",银行预留电话:" + loginUser.getReservePhone() + ">" + Convert.toStr(params.get("reservephone"))
                    + ",省名称:" + loginUser.getReservePhone() + ">" + Convert.toStr(params.get("provName"))
                    + ",市名称:" + loginUser.getReservePhone() + ">" + Convert.toStr(params.get("preaName"))
                    + ",银行名称:" + loginUser.getReservePhone() + ">" + Convert.toStr(params.get("bankName"))
            );
            userLog.setOperationId((Integer) params.get("operationid"));
            userLog.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            pvUserLogMapper.insert(userLog);
            message.setMessage("操作成功");
            message.setCode("200");
            message.setSuccess(true);
        } catch (Exception e) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("操作失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }
        return message;
    }


    /**
     * 乡村振兴取用户信息
     */
    @Override
    public BusinessMessage userInfo(PvUserParam pvUserParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            if (StringUtils.isBlank(Convert.toStr(pvUserParam.getPhone()))) {
                message.setCode("-1");
                message.setMessage("用户电话号码不能为空，请重新输入");
                message.setSuccess(false);
                return message;
            }
            PvLoginUser pvLoginUser = new PvLoginUser();
            pvLoginUser.setPhone(pvUserParam.getPhone());

            PvLoginUser pvLoginUserData = hpcUserMappers.userInfo(pvLoginUser);

            message.setData(pvLoginUserData);
            message.setSuccess(true);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
        } catch (Exception e) {
            message.setSuccess(false);
            message.setMessage(Status.fail);
            message.setCode(Status.failCode);
            e.printStackTrace();
        }
        return message;
    }

    /**
     * 用户启用/封号
     *
     * @param pvUserParam
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage updateUserStatus(PvUserParam pvUserParam) {
        BusinessMessage message = new BusinessMessage();
        PvLoginUser pvLoginUser = new PvLoginUser();
        if (pvUserParam.getUserId() == null) {
            message.setCode("-1");
            message.setMessage("主键不能为空");
            message.setSuccess(false);
            return message;
        }
        if (pvUserParam.getStatus() == null) {
            message.setCode("-1");
            message.setMessage("状态不能为空");
            message.setSuccess(false);
            return message;
        }

        pvLoginUser.setId(pvUserParam.getUserId());
        pvLoginUser.setStatus(pvUserParam.getStatus());
        pvLoginUser.setUpdateTime(new Date());
        pvLoginUser.setDisableUser(HpcUserEnum.DISABLE_ADMIN.getCode());
        pvLoginUser.setOperatorId(pvUserParam.getOperatorId());
        hpcUserMappers.updateById(pvLoginUser);
        message.setCode("200");
        message.setMessage("操作成功");
        message.setSuccess(true);
        return message;
    }

    @Override
    public BusinessMessage slbRecharge(SlbRechargeParam param) {
        BusinessMessage message = new BusinessMessage();
        log.info("调用开始{}", param);
        if (ObjectUtils.isEmpty(param.getPhone()) || ObjectUtils.isEmpty(param.getOrderNum())) {
            message.setCode("-1");
            message.setMessage("参数不完整!");
            message.setSuccess(false);
            log.info("参数不完整参数不完整");
            return message;
        }
        if (param.getOfflineRechargeAmount() <= 0) {
            message.setCode("-1");
            message.setMessage("请输入正确金额后重试!");
            message.setSuccess(false);
            log.info("请输入正确金额后重试");
            return message;
        }
        String key = "SLB_RECHARGE" + param.getOrderNum();
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, 1, 5, TimeUnit.MINUTES);
        if (!lock) {
            message.setMessage("正在购买，请勿重复提交");
            message.setCode("-1");
            message.setSuccess(false);
            log.info("正在购买，请勿重复提交{}", key);
            return message;
        }
        try {
            PvLoginUser pvLoginUser = hpcUserMappers.selectOne(new QueryWrapper<>(new PvLoginUser() {{
                setPhone(param.getPhone());
            }}));
            if (ObjectUtils.isEmpty(pvLoginUser)) {
                message.setCode("-1");
                message.setMessage("用户不存在");
                message.setSuccess(false);
                log.info("用户不存在");
                return message;
            }
            //幂等校验
            LambdaQueryWrapper<PvOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PvOrder::getSerialNumber, "S" + param.getOrderNum());
            List<PvOrder> pvOrders = pvOrderMapper.selectList(wrapper);
            if (ObjectUtils.isNotEmpty(pvOrders)) {
                //此处-2为搜了宝判定使用，不可更改
                message.setCode("-2");
                message.setMessage("订单已存在,请勿重复提交!");
                message.setSuccess(false);
                log.info("订单已存在,请勿重复提交!");
                return message;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("userId", pvLoginUser.getId());
            map.put("loginUserId", pvLoginUser.getId());
            map.put("offlineRechargeAmount", param.getOfflineRechargeAmount());
            //type=1表示搜了宝充值
            map.put("type", 1);
            map.put("orderNum", param.getOrderNum());
            map.put("paymentChannel", param.getPaymentChannel());
            message = this.offlineRecharge(map);
            log.info("调用成功{}", param);
            return message;
        } finally {
            redisTemplate.delete(key);
        }
    }

    @Override
    public BusinessMessage queryUserDetail(AuthenticationParam param) {
        BusinessMessage message = new BusinessMessage();
        if (ObjectUtils.isEmpty(param.getUserId())) {
            message.setCode("-1");
            message.setMessage("用户id不能为空!");
            message.setSuccess(false);
            return message;
        }
        PvLoginUser pvLoginUser = pvUserLoginMapper.selectById(param.getUserId());
        PvLoginUserVo pvLoginUserVo = new PvLoginUserVo();
        BeanUtils.copyProperties(pvLoginUser, pvLoginUserVo);
        message.setData(pvLoginUserVo);
        message.setCode("200");
        message.setMessage("操作成功");
        message.setSuccess(true);
        return message;
    }

    @Override
    public BusinessMessage updateAuditStatus(AuthenticationParam param) {
        BusinessMessage message = new BusinessMessage();
        if (ObjectUtils.isEmpty(param.getUserId()) || ObjectUtils.isEmpty(param.getAuditStatus())) {
            message.setCode("-1");
            message.setMessage("参数不完整!");
            message.setSuccess(false);
            return message;
        }
        LambdaQueryWrapper<PvLoginUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PvLoginUser::getId, param.getUserId());
        wrapper.eq(PvLoginUser::getAuditStatus, HpcUserEnum.APPROVED.getCode());
        wrapper.eq(PvLoginUser::getToExamine, HpcUserEnum.CERTIFICATION_AUDIT.getCode());
        PvLoginUser pvLoginUser = pvUserLoginMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pvLoginUser)) {
            message.setCode("-1");
            message.setMessage("请勿重复提交!");
            message.setSuccess(false);
            return message;
        } else {
            if (param.getAuditStatus().equals(HpcUserEnum.APPROVED.getCode())) {
                pvLoginUser.setAuditTime(new Date());
                pvLoginUser.setToExamine(HpcUserEnum.CERTIFIED.getCode());
            }
            pvLoginUser.setAuditStatus(param.getAuditStatus());
            pvUserLoginMapper.updateById(pvLoginUser);
            // 通过或者驳回添加短信通知
            if (param.getAuditStatus().equals(HpcUserEnum.APPROVED.getCode()) || param.getAuditStatus().equals(HpcUserEnum.APPROVAL_REJECTION.getCode())) {
                if (param.getAuditStatus().equals(HpcUserEnum.APPROVED.getCode())) {// 通过
                    String[] msgs = {pvLoginUser.getAccounts()};
                    SmsSingleSenderResult result1 = TencentSmsUtils.smsSingleSender(
                            SmsConstant.appid,
                            SmsConstant.appkey,
                            "86", pvLoginUser.getPhone(), SmsConstant.REGISTRATION_NOTICE, msgs,
                            "椒易宝", "", "");
                } else {// 驳回

                }

            }
            message.setCode(Status.successCode);
            message.setMessage(Status.success);
            message.setSuccess(true);
            return message;
        }
    }

    @Override
    public BusinessMessage sysUserList() {
        BusinessMessage message = new BusinessMessage();
        List<SysUserRsp> queryRechargeRole = sysUserHpcMapper.queryRechargeRole();
        message.setData(queryRechargeRole);
        message.setCode(Status.successCode);
        message.setMessage(Status.success);
        message.setSuccess(true);
        return message;
    }

    @Override
    public void export(HoldProductListParam param) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String curTime = simpleDateFormat.format(new Date((Long) param.getCurTimeLong()));;
        String yesterday = null;
        if (ObjectUtils.isEmpty(param.getAccounts()) || ObjectUtils.isEmpty(param.getCurTimeLong())) {
           return;
        }
        try {
            Date toDayDate = simpleDateFormat.parse(curTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(toDayDate);
            calendar.add(Calendar.DAY_OF_MONTH, -1);//减一天
            yesterday = simpleDateFormat.format(calendar.getTime());
            List<HoldProductEntity> list = getHoldProductEntities(param ,curTime, yesterday);
            // 添加汇总
            extracted(list,curTime);
            PoiUtil.exportExcelWithStream("客户总报表_"+param.getAccounts()+"_"+curTime+".xls", HoldProductEntity.class, list);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     *  添加汇总
     * @param list
     */
    private void extracted(List<HoldProductEntity> list,String curTime) {
        Double drDayBuyNum = 0D;
        Double drSFNum = 0D;
        Double drSellSFNum = 0D;
        Double yjTHNum = 0D;
        Double drTHNum = 0D;
        Double srDayHoldNum = 0D;
        Double drDaySellNum = 0D;
        Double drSFNumProductId = 0D;
        Double drSumNum = 0D;
        for (HoldProductEntity holdProductEntity : list) {
            srDayHoldNum += holdProductEntity.getSrDayHoldNum();
            drDaySellNum += holdProductEntity.getDrDaySellNum();
            drSFNumProductId += holdProductEntity.getDrSFNumProductId();
            drSumNum += holdProductEntity.getDrSumNum();
            drDayBuyNum += holdProductEntity.getDrDayBuyNum();
            drSFNum += holdProductEntity.getDrSFNum();
            drSellSFNum += holdProductEntity.getDrSellSFNum();
            yjTHNum += holdProductEntity.getYjTHNum();
            drTHNum += holdProductEntity.getDrTHNum();
        }
        HoldProductEntity end = new HoldProductEntity();
        end.setProductName("汇总");
        end.setSrDayHoldNum(srDayHoldNum);
        end.setDrDaySellNum(drDaySellNum);
        end.setDrSFNumProductId(drSFNumProductId);
        end.setDrSumNum(drSumNum);
        end.setDrDayBuyNum(drDayBuyNum);
        end.setDrSFNum(drSFNum);
        end.setDrSellSFNum(drSellSFNum);
        end.setYjTHNum(yjTHNum);
        end.setDrTHNum(drTHNum);
        end.setDcDate(curTime);
        list.add(end);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage experienceRecharge(ExperienceGoldParam params) {
        BusinessMessage message = new BusinessMessage();

        String lockKey="EXPERIENCE_LOCK_"+params.getUserId();
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockKey,  "1", 2,TimeUnit.MINUTES);
        if (!lock) {
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("订单处理中,请勿重复提交!");
            return message;
        }

        BigDecimal bigDecimal = new BigDecimal("10000");
        if (ObjectUtils.isEmpty(params.getExperienceRechargeAmount()) || params.getExperienceRechargeAmount().compareTo(bigDecimal)!=0) {
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("非法参数");
            return message;
        }
        if (ObjectUtils.isEmpty(params.getUserId())) {
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("userId不能为空");
            return message;
        }
        if (ObjectUtils.isEmpty(params.getLoginUserId())){
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("操作人ID不能为空");
            return message;
        }
        //校验用户状态合法性
        PvLoginUser loginUser = pvUserLoginMapper.selectById(params.getUserId());
        if(ObjectUtils.isEmpty(loginUser) || loginUser.getUserType() == 1){
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("该用户已是体验用户!");
            return message;
        }
        try {
            //更新用户类型
            PvLoginUser pvLoginUser = new PvLoginUser();
            pvLoginUser.setId(params.getUserId());
            pvLoginUser.setUserType(1);
            pvUserLoginMapper.updateById(pvLoginUser);

            //生成订单明细
            PvOrder pvOrder = new PvOrder();
            //生成订单号
            String orderNum = OrderNumGeneration.generateOrderId();
            pvOrder.setSerialNumber(orderNum);
            pvOrder.setRemark("体验用户支付购货金额:" + params.getExperienceRechargeAmount());
            pvOrder.setPurchaseMethod(3);
            String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            pvOrder.setCreateTime(currentTime);
            pvOrder.setUpdatedAt(new Date());
            pvOrder.setDelistingUserId(params.getUserId());
            pvOrder.setPaymentChannel(25);
            pvOrder.setPaymentState(1);
            pvOrder.setTotalAmount(params.getExperienceRechargeAmount());
            pvOrder.setUserType(pvLoginUser.getUserType());
            pvOrderMapper.insert(pvOrder);
            boolean status = this.moneyOperation(params.getUserId(), 1, params.getExperienceRechargeAmount());
            if (false == status) {
                message.setSuccess(false);
                message.setCode("-2");
                message.setMessage("用户支付购货金额失败");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return message;
            }
            pvWalletLogMapper.insertWalletLogByUserId(params.getUserId(), pvOrder.getId(), params.getExperienceRechargeAmount(), "体验充值", currentTime, 3, params.getLoginUserId());
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("支付成功");
        }catch (Exception e){
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("支付失败");
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return message;
    }

    @Override
    public BusinessMessage experienceUserList(UserListParam params) {
        BusinessMessage<Object> message = new BusinessMessage<>();
        Integer pageNo = params.getPageNo();
        Integer pageSize = params.getPageSize();
        if (pageNo == null || pageNo <= 0) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }
        // 设置分页参数
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> lists = pvUserLoginMapper.experienceUserList(params);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(lists);
        message.setSuccess(true);
        message.setData(pageInfo);
        message.setCode("200");
        message.setMessage("查询成功");
        return message;
    }
    @Resource
    private PvWalletShopMapper pvWalletShopMapper;
    @Resource
    private PvLoginUserMapper pvLoginUserMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage cancelExperience(Integer userId) {
        BusinessMessage message = new BusinessMessage();
        // 登录用户校验
        String currentTime = LocalDateTime.now() .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        SysUserHpcEntity currentLoginUser = loginService.getCurrentLoginUser();
        PvLoginUser targetUser = hpcUserMappers.selectById(userId);
        String flag = "cancelExperience_"+userId;
        try{
            BusinessMessage message1 = parameterVerify(userId, message, currentLoginUser, targetUser, flag);
            if (message1 != null) return message1;
            // 计算平台钱包和商户余额
            PvWallet pvWallet = pvWalletMapper.selectOne(new QueryWrapper<>(new PvWallet() {{
                setUserId(targetUser.getId());
            }}));
            List<PvWalletShop> pvWalletShopList = pvWalletShopMapper.selectList(
                    Wrappers.lambdaQuery(PvWalletShop.class)
                            .eq(PvWalletShop::getUserId, targetUser.getId())
                            .gt(PvWalletShop::getAvailableBalance, BigDecimal.ZERO));
            BigDecimal oneW = new BigDecimal( "10000");
            // 判断总额是否满足取消条件
            BusinessMessage message2 = verifyMoney(message, pvWallet, pvWalletShopList, oneW);
            if (message2 != null) return message2;
            // 平台余额充足,扣减平台钱包,
            if(pvWallet.getAvailableBalance().compareTo(oneW)>=0){
                BusinessMessage message3 = subStructPlatformWallet(targetUser, oneW, message, "体验金取消失败", currentTime, currentLoginUser);
                if (message3 != null) return message3;
            }
            // 平台余额不够, 先扣平台再扣减商家钱包
            BigDecimal walletBalance = pvWallet.getAvailableBalance();
            if(walletBalance.compareTo(oneW)<0){
                if (walletBalance.compareTo(BigDecimal.ZERO)>0){
                    BusinessMessage message3 = subStructPlatformWallet(targetUser, walletBalance, message, "平台体验金取消失败", currentTime, currentLoginUser);
                    if (message3 != null) {
                        return message3;
                    }
                }
                // 扣除商家钱包
                subStructShopWallet(currentLoginUser, targetUser, pvWallet, pvWalletShopList, oneW);
            }
            // 取消成功更改用户体验用户类型
            targetUser.setId(userId);
            targetUser.setUserType(0);
            pvLoginUserMapper.updateById(targetUser);
            // 生成操作流水
            insertOpLog(targetUser, currentLoginUser);
            message.setCode("200");
            message.setMessage("操作成功");
            message.setSuccess(true);
            // 操作完成删除正在操作标识
            redisTemplate.delete(flag);
        }catch(Exception e){
            message.setSuccess(false);
            message.setMessage("体验金取消失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            redisTemplate.delete(flag);
            e.printStackTrace();
        }
        return message;
    }

    private void subStructShopWallet(SysUserHpcEntity currentLoginUser, PvLoginUser targetUser, PvWallet pvWallet, List<PvWalletShop> pvWalletShopList, BigDecimal oneW) {
        BigDecimal residueBalance = oneW.subtract(pvWallet.getAvailableBalance());
        //循环扣减商家余额
        for (PvWalletShop pvWalletShop : pvWalletShopList) {
            Integer shopId = pvWalletShop.getShopId();
            if(residueBalance.compareTo(BigDecimal.ZERO)>0){
                BigDecimal shopBalance = pvWalletShop.getAvailableBalance();
                if(shopBalance.compareTo(residueBalance)>=0){
                    subStructShopWalletAndInsertLog(currentLoginUser, targetUser, pvWalletShop, shopId, residueBalance);
                    break;
                }else{
                    subStructShopWalletAndInsertLog(currentLoginUser, targetUser, pvWalletShop, shopId, shopBalance);
                    residueBalance = residueBalance.subtract(shopBalance);
                }
            }
        }
    }

    @Nullable
    private BusinessMessage subStructPlatformWallet(PvLoginUser targetUser, BigDecimal oneW, BusinessMessage message, String 体验金取消失败, String currentTime, SysUserHpcEntity currentLoginUser) throws Exception {
        boolean status = this.moneyOperation(targetUser.getId(), 2, oneW);
        if (!status) {
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage(体验金取消失败);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return message;
        }
        pvWalletLogMapper.insertWalletLogByUserId(targetUser.getId(),null, oneW,"取消体验金" + oneW +"元", currentTime,
                18, currentLoginUser.getUserId().intValue());
        return null;
    }

    @Nullable
    private BusinessMessage verifyMoney(BusinessMessage message, PvWallet pvWallet, List<PvWalletShop> pvWalletShopList, BigDecimal oneW) {
        BigDecimal pvWalletShopBalance = pvWalletShopList.stream().map(gzWalletShop -> ObjectUtils.isEmpty(gzWalletShop.getAvailableBalance()) ?
                new BigDecimal(0) : gzWalletShop.getAvailableBalance()).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalBalance = pvWallet.getAvailableBalance().add(pvWalletShopBalance);
        if(totalBalance.compareTo(oneW)<0){
            message.setCode("-1");
            message.setMessage("余额不足, 请充值后重试");
            message.setSuccess(false);
            return message;
        }
        return null;
    }

    private void subStructShopWalletAndInsertLog(SysUserHpcEntity currentLoginUser, PvLoginUser targetUser, PvWalletShop pvWalletShop, Integer shopId, BigDecimal shopBalance) {
        pvWalletShopMapper.updateWalletShopInfoByShopIdAndUserId(shopId, pvWalletShop.getUserId(), shopBalance,2);
        PvWalletShopLog pvWalletShopLog = new PvWalletShopLog();
        pvWalletShopLog.setUserId(targetUser.getId());
        pvWalletShopLog.setOrderId(null);
        pvWalletShopLog.setRemarks("取消体验用户:" + shopBalance + "元");
        pvWalletShopLog.setCreateTime(now());
        pvWalletShopLog.setTypes(18);
        pvWalletShopLog.setOperation(currentLoginUser.getUserId().intValue());
        pvWalletShopLog.setShopId(shopId);
        pvWalletShopLog.setChangeBalance(shopBalance);
        pvWalletShopMapper.addPvWalletShopLog(pvWalletShopLog);
    }

    private void insertOpLog(PvLoginUser loginUser, SysUserHpcEntity currentLoginUser) {
        CancelExperienceLog experienceLog = new CancelExperienceLog();
        experienceLog.setUserId(loginUser.getId());
        experienceLog.setUserName(loginUser.getRealName());
        experienceLog.setOperatorId(currentLoginUser.getUserId());
        experienceLog.setOperatorName(currentLoginUser.getUsername());
        cancelExperienceLogMapper.insert(experienceLog);
    }

    @Nullable
    private BusinessMessage parameterVerify(Integer userId, BusinessMessage message, SysUserHpcEntity currentLoginUser, PvLoginUser loginUser, String flag) {
        if (userId == null) {
            message.setCode("-1");
            message.setMessage("用户id不能为空!");
            message.setSuccess(false);
            return message;
        }
        if (ObjectUtils.isEmpty(currentLoginUser)){
            message.setCode("-1");
            message.setMessage("无登录用户!");
            message.setSuccess(false);
            return message;
        }
        if (ObjectUtils.isEmpty(loginUser)){
            message.setCode("-1");
            message.setMessage("该用户不存在!");
            message.setSuccess(false);
            return message;
        }
        if (loginUser.getUserType()==0){
            message.setCode("-1");
            message.setMessage("普通用户不可取消!");
            message.setSuccess(false);
            return message;
        }
        // 重复校验
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(flag,"1",2, TimeUnit.MINUTES);
        if (!lock) {
            message.setCode("-1");
            message.setMessage("该会员正在处理中，请勿重复提交!");
            message.setSuccess(false);
            return message;
        }
        return null;
    }

    @Override
    public void newMasterAccountExcel(HttpServletResponse response,MasterAccountExcelParam param) {
        try {
            if (ObjectUtils.isEmpty(param)){
                return;
            }
            List<NewMasterAccountExcelVo> voList=pvProductGlMapper.queryAccount();
            String format = param.getStartTime();
            String date = DateUtils.getBeforeDay(1,format);
            //商品id
            List<Integer> productId = voList.stream().map(NewMasterAccountExcelVo::getProductId).collect(Collectors.toList());
            //释放数量
            List<ReleaseNumber> releaseNumber=pvReleaseBaseMapper.queReleaseNumber(date,productId);
            Map<Integer, ReleaseNumber> numberMap =new HashMap<>();
            if (releaseNumber.size()>0&&releaseNumber.get(0)!=null){
                numberMap = releaseNumber.stream().collect(Collectors.toMap(ReleaseNumber::getBsNum, t -> t));
            }
            for (NewMasterAccountExcelVo vo:voList){
                //总账户余额
                BigDecimal accountBalances=pvWalletLogMapper.getAccountBalances(format,vo.getUserId());
                vo.setAccountBalance(accountBalances);
                //手续费账户余额
                BigDecimal commissionBalance=pvWalletLogMapper.getAccountBalances(format,vo.getPoundageUserId());
                vo.setCommissionBalance(commissionBalance);
                //昨日持有数
                BigDecimal totalHoldings=pvPossessionGoodsMapper.totalHoldings(vo.getUserId(),vo.getProductId(),format);
                ReleaseNumber number = numberMap.get(vo.getProductId());
                if (ObjectUtils.isNotEmpty(number)){
                    BigDecimal subtract = totalHoldings.subtract(number.getBsAmount());
                    vo.setTotalHoldings(subtract);
                    vo.setTotalReleases(number.getBsAmount());
                }else {
                    vo.setTotalReleases(new BigDecimal("0.00"));
                    vo.setTotalHoldings(totalHoldings);
                }
            }
            List<List<Object>> rows = new ArrayList();
            ExcelData data = new ExcelData();
            data.setName("总账号信息导出");//sheet表名称
            //表头
            List<String> titles = new ArrayList();
            titles.add("总账号id");
            titles.add("总账户余额");
            titles.add("手续费用户id");
            titles.add("手续费账号余额");
            titles.add("商品id");
            titles.add("商品名称");
            titles.add("店铺id");
            titles.add("总释放数量");
            titles.add("总持有数量");
            data.setTitles(titles);
            for (NewMasterAccountExcelVo masterAccountExcelVo : voList) {
                List<Object> row1 = new ArrayList();
                row1.add(masterAccountExcelVo.getUserId());
                row1.add(masterAccountExcelVo.getAccountBalance());
                row1.add(masterAccountExcelVo.getPoundageUserId());
                row1.add(masterAccountExcelVo.getCommissionBalance());
                row1.add(masterAccountExcelVo.getProductId());
                row1.add(masterAccountExcelVo.getProductName());
                row1.add(masterAccountExcelVo.getShopId());
                row1.add(masterAccountExcelVo.getTotalReleases());
                row1.add(masterAccountExcelVo.getTotalHoldings());
                rows.add(row1);
            }
            data.setRows(rows);
            ExportExcelUtils.exportExcel(response, "总账号数据信息导出.xlsx", data);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    @Override
    public BusinessMessage accountBalance(AccountBalanceParam param) {
        BusinessMessage message = new BusinessMessage();
        if (param.getUserId() == null) {
            message.setCode(Status.failCode);
            message.setMessage("用户id不能为空");
            message.setSuccess(false);
            return message;
        }
        Integer pageNo = param.getPageNo();
        Integer pageSize = param.getPageSize();
        if (pageNo == null || Integer.valueOf(pageNo) <= 1) {
            pageNo = 1;
        }
        if (pageSize == null || Integer.valueOf(pageSize) <= 1) {
            pageSize = 10;
        }
        PageHelper.startPage(pageNo, pageSize);
        LambdaQueryWrapper<PvWalletLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PvWalletLog::getUserId, param.getUserId());
        if (param.getBeginTime() != null && param.getBeginTime() != "" && param.getEndTime() != null && param.getEndTime() != "") {
            wrapper.between(PvWalletLog::getCreateTime, param.getBeginTime(), param.getEndTime());
        }
        if (param.getType() != null && param.getType() != 0) {
            wrapper.eq(PvWalletLog::getTypes, param.getType());
        }
        if (param.getOrderId() != null && param.getOrderId() != "") {
            wrapper.eq(PvWalletLog::getOderId, param.getOrderId());
        }
        wrapper.orderByDesc(PvWalletLog::getCreateTime);
        List<PvWalletLog> gzWalletLogs = pvWalletLogMapper.selectList(wrapper);
        PageInfo<PvWalletLog> pageInfo = new PageInfo<>(gzWalletLogs);
        message.setSuccess(true);
        message.setMessage(Status.success);
        message.setCode(Status.successCode);
        message.setData(pageInfo);
        return message;
    }

    @Override
    public BusinessMessage shopAccountBalance(AccountBalanceParam param) {
        BusinessMessage message = new BusinessMessage();
        if (param.getUserId() == null) {
            message.setCode(Status.failCode);
            message.setMessage("用户id不能为空");
            message.setSuccess(false);
            return message;
        }
        Integer pageNo = param.getPageNo();
        Integer pageSize = param.getPageSize();
        if (pageNo == null || Integer.valueOf(pageNo) <= 1) {
            pageNo = 1;
        }
        if (pageSize == null || Integer.valueOf(pageSize) <= 1) {
            pageSize = 10;
        }
        PageHelper.startPage(pageNo, pageSize);
        List<PvWalletShopLogVo> pvWalletShopLogVos = pvWalletShopLogMapper.getWalletShopLog(param);
        PageInfo<PvWalletShopLogVo> pageInfo = new PageInfo<>(pvWalletShopLogVos);
        message.setSuccess(true);
        message.setMessage(Status.success);
        message.setCode(Status.successCode);
        message.setData(pageInfo);
        return message;
    }

    @Override
    public BusinessMessage consignmentTradeDetail(ConsignmentParam consignmentParam) {
        // 设置分页参数
        BusinessMessage message = new BusinessMessage();
        if (consignmentParam.getUserId() == null) {
            message.setMessage("用户id不能为空");
            message.setSuccess(false);
            message.setCode(Status.failCode);
            return message;
        }
        try {
            Map map = new HashMap<>();
            PageHelper.startPage(consignmentParam.getPageNo(),consignmentParam.getPageSize());
            List<ConsignmentGoodVo> consignmentGoods = pvLoginUserMapper.consignmentTradeDetail(consignmentParam);
            PageInfo<ConsignmentGoodVo> pageInfo = new PageInfo<>(consignmentGoods);
            PvBuySellSummaryVo buySellSummary = pvLoginUserMapper.tradeSummary(consignmentParam);
            map.put("pageInfo", pageInfo);
            if (pageInfo.getSize()<=0){
                message.setData(map);
                message.setMessage("无数据");
                message.setSuccess(true);
                message.setCode(Status.successCode);
                return message;
            }
            map.put("sumProductNum", buySellSummary.getSumProductNum());
            map.put("sumTotal", buySellSummary.getSumTotal());
            map.put("sumSXF", buySellSummary.getSumSXF());
            map.put("platformFWF", buySellSummary.getPlatformFWF());
            map.put("sumGWJ", buySellSummary.getSumGWJ());
            map.put("sumSPJL", buySellSummary.getSumSPJL());

            message.setData(map);
            message.setMessage(Status.success);
            message.setSuccess(true);
            message.setCode(Status.successCode);
        } catch (Exception e) {
            message.setMessage(Status.fail);
            message.setSuccess(false);
            message.setCode(Status.failCode);
            e.printStackTrace();
        }
        return message;
    }

    @Override
    public BusinessMessage exUserTransference(MultipartFile file) {
        BusinessMessage message = new BusinessMessage();
        SysUserHpcEntity currentLoginUser = loginService.getCurrentLoginUser();
        if (ObjectUtils.isEmpty(currentLoginUser)){
            message.setCode("-1");
            message.setMessage("无登录用户!");
            message.setSuccess(false);
            return message;
        }
        boolean time = htTimeService.thinkTime();
        if (time == false) {
            message.setCode("-1");
            message.setSuccess(false);
            message.setMessage("不在转让时间");
            return message;
        }
        PvHoliday holiday = pvHolidayMapper.selectOne(new QueryWrapper<>(new PvHoliday() {{
            setHoliday(DateUtils.ymd.format(new Date()));
        }}));
        if (null != holiday) {
            message.setCode(Status.failCode);
            message.setSuccess(false);
            message.setMessage("不是工作日，无法交易");
            return message;
        }
        try {
            log.info("用户{}操作转让代持商品，时间：[{}]",currentLoginUser.getUserId(),new Date());
            List<ExUserTransferenceVo> exUserTransferenceVos = PoiUtil.importExcel(file, 0, 1, ExUserTransferenceVo.class);
            if (exUserTransferenceVos.size()>500){
                message.setSuccess(false);
                message.setCode("-1");
                message.setMessage("数据量超出限制范围!");
                return message;
            }
            List<ExUserTransferenceVo> list = new ArrayList<>();
            List<Integer> userIdlist = exUserTransferenceVos.stream().map(ExUserTransferenceVo::getUserId).filter(Objects::nonNull).collect(Collectors.toList());
            //用户校验，查询是否有部分和条件的
            QueryWrapper<PvLoginUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id,accounts,phone,real_name as realName");
            queryWrapper.in("id",userIdlist).and(i->i.notIn("user_type",1).or().notIn("status",3));
            List<PvLoginUser> pvLoginUsers = pvLoginUserMapper.selectList(queryWrapper);
            if (pvLoginUsers.size()>0){
                list = pvLoginUsers.stream().map(user -> {
                    ExUserTransferenceVo vo = new ExUserTransferenceVo();
                    vo.setUserId(user.getId());
                    vo.setAccounts(user.getAccounts());
                    vo.setPhone(user.getPhone());
                    vo.setUserName(user.getRealName());
                    vo.setRemarks("不是体验用户或未封号!");
                    return vo;
                }).collect(Collectors.toList());
            }
            if (list.size()>0){
                message.setData(list);
                message.setSuccess(false);
                message.setCode("-1");
                message.setMessage("数据异常，请核对后重试!");
                return message;
            }
            String property = env.getProperty("xczx.experienceUnblocking");
            Map map = restTemplate.postForObject(property, exUserTransferenceVos, Map.class);
            message.setCode("200");
            message.setMessage("操作成功");
            message.setSuccess(true);
        }catch (Exception e){
            log.info("用户[{}]操作转让代持商品操作异常，原因：{}",currentLoginUser.getUserId(),e.getMessage());
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("数据异常，请核对后重试!");
           e.printStackTrace();
        }
        return message;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage deductible(IdentityRevocationVo vo) {
        BusinessMessage message = new BusinessMessage();
        // 登录用户校验
        String currentTime = LocalDateTime.now() .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        SysUserHpcEntity currentLoginUser = loginService.getCurrentLoginUser();
        PvLoginUser targetUser = hpcUserMappers.selectById(vo.getUserId());
        String flag = RedisKeyUtil.DEDUCTIBLE_LOCK+vo.getUserId();
        try{
            if (ObjectUtils.isEmpty(vo.getPersonalAmount())|| vo.getPersonalAmount().compareTo(new BigDecimal("10000.00"))<0){
                message.setCode("-1");
                message.setMessage("请输入正确金额!");
                message.setSuccess(false);
                return message;
            }
            BusinessMessage message1 = parameterVerify(vo.getUserId(), message, currentLoginUser, targetUser, flag);
            if (message1 != null){
                return message;
            }
            // 计算平台钱包和商户余额
            PvWallet pvWallet = pvWalletMapper.selectOne(new QueryWrapper<>(new PvWallet() {{
                setUserId(targetUser.getId());
            }}));
            List<PvWalletShop> pvWalletShopList = pvWalletShopMapper.selectList(
                    Wrappers.lambdaQuery(PvWalletShop.class)
                            .eq(PvWalletShop::getUserId, targetUser.getId())
                            .gt(PvWalletShop::getAvailableBalance, BigDecimal.ZERO));
            BigDecimal oneW = vo.getPersonalAmount();
            // 判断总额是否满足取消条件
            BusinessMessage message2 = inspectionAmount(message, pvWallet, pvWalletShopList, vo);
            if (message2 != null){
                return message2;
            }
            // 平台余额充足,扣减平台钱包,
            if(pvWallet.getAvailableBalance().compareTo(oneW)>=0){
                BusinessMessage message3 = subStructPlatformWallet(targetUser, oneW, message, "体验金取消失败", currentTime, currentLoginUser);
                if (message3 != null){
                    return message3;
                }
            }
            // 平台余额不够, 先扣平台再扣减商家钱包
            BigDecimal walletBalance = pvWallet.getAvailableBalance();
            if(walletBalance.compareTo(oneW)<0){
                if (walletBalance.compareTo(BigDecimal.ZERO)>0){
                    BusinessMessage message3 = subStructPlatformWallet(targetUser, walletBalance, message, "平台体验金取消失败", currentTime, currentLoginUser);
                    if (message3 != null){
                        return message3;
                    }
                }
                // 扣除商家钱包
                subStructShopWallet(currentLoginUser, targetUser, pvWallet, pvWalletShopList, oneW);
            }
            // 取消成功更改用户体验用户类型
            targetUser.setId(vo.getUserId());
            targetUser.setUserType(0);
            targetUser.setStatus(Convert.toShort(0));
            pvLoginUserMapper.updateById(targetUser);
            // 生成操作流水
            insertOpLog(targetUser, currentLoginUser);
            message.setCode("200");
            message.setMessage("操作成功");
            message.setSuccess(true);
        }catch(Exception e){
            vo.setRemarks(e.getMessage());
            message.setData(vo);
            message.setSuccess(false);
            message.setMessage("体验金取消失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("扣除体验金操作失败，原因{}",e.getMessage());
        }finally {
            redisTemplate.delete(flag);
        }
        return message;
    }

    @Nullable
    private BusinessMessage inspectionAmount(BusinessMessage message, PvWallet pvWallet, List<PvWalletShop> pvWalletShopList, IdentityRevocationVo vo) {
        BigDecimal pvWalletShopBalance = pvWalletShopList.stream().map(gzWalletShop -> ObjectUtils.isEmpty(gzWalletShop.getAvailableBalance()) ?
                new BigDecimal(0) : gzWalletShop.getAvailableBalance()).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalBalance = pvWallet.getAvailableBalance().add(pvWalletShopBalance);
        if(totalBalance.compareTo(vo.getPersonalAmount())<0){
            vo.setPersonalAmount(totalBalance);
            vo.setRemarks("余额不足,扣款失败!");
            message.setData(vo);
            message.setCode("-1");
            message.setMessage("余额不足, 请充值后重试");
            message.setSuccess(false);
            return message;
        }
        return null;
    }

}
